//
//  UIViewController+MONavigation.m
//  WCImApp
//
//  Created by alfie on 2019/10/31.
//  Copyright © 2019 WCImApp. All rights reserved.
//

#import "UIViewController+MONavigation.h"
#import <objc/runtime.h>
#import "NSObject+MOSwizzleMethod.h"

@implementation UIViewController (MONavigation)

static const char *MONavigationViewKey        = "MONavigationViewKey";
static const char *MOHidesNavigationBarKey    = "MOHidesNavigationBarKey";
static const char *MOKeyboardOffsetKey        = "MOKeyboardOffsetKey";
static const char *MOKeyboardShouldObserveKey = "MOKeyboardShouldObserveKey";
static const char *MONavigationStyleKey       = "MONavigationStyleKey";
+(void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleInstanceMethodWithClass:[UIViewController class] originalSel:@selector(viewWillAppear:) swizzledSel:@selector(af_viewWillAppear:)];
        [self swizzleInstanceMethodWithClass:[UIViewController class] originalSel:@selector(viewWillDisappear:) swizzledSel:@selector(af_viewWillDisappear:)];
        [self swizzleInstanceMethodWithClass:[UIViewController class] originalSel:NSSelectorFromString(@"dealloc") swizzledSel:@selector(af_dealloc)];
        [self swizzleInstanceMethodWithClass:[UIViewController class] originalSel:@selector(dismissViewControllerAnimated:completion:) swizzledSel:@selector(af_dismissViewControllerAnimated:completion:)];
        [self swizzleInstanceMethodWithClass:[UIViewController class] originalSel:@selector(presentViewController:animated:completion:) swizzledSel:@selector(af_presentViewController:animated:completion:)];
    });
}


- (void)af_viewWillAppear:(BOOL)animated {
    [self af_viewWillAppear:animated];
    if (self.hidesNavigationBar) {
        [self.navigationController setNavigationBarHidden:YES animated:animated];
    }
}

- (void)af_viewWillDisappear:(BOOL)animated {
    [self af_viewWillDisappear:animated];
    if (self.hidesNavigationBar) {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }
}

- (void)af_dealloc {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UIViewControllerDealloc" object:self];
//    QHLog(@" ------------------------------------------------------------=== %@  ----af_dealloc--", NSStringFromClass([self class]));
    [self af_dealloc];
}

- (void)setHidesNavigationBar:(BOOL)hidesNavigationBar {
    [self.navigationController setNavigationBarHidden:hidesNavigationBar animated:NO];
    objc_setAssociatedObject(self, MOHidesNavigationBarKey, @(hidesNavigationBar), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)hidesNavigationBar {
    return [objc_getAssociatedObject(self, MOHidesNavigationBarKey) boolValue];
}


- (void)setNavigationView:(MONavigationView *)navigationView {
    objc_setAssociatedObject(self, MONavigationViewKey, navigationView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (MONavigationView *)navigationView {
    return objc_getAssociatedObject(self, MONavigationViewKey);
}

- (void)setKeyboardOffset:(CGFloat)keyboardOffset {
    NSNumber *number = [NSNumber numberWithFloat:keyboardOffset];
    objc_setAssociatedObject(self, MOKeyboardOffsetKey, number, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGFloat)keyboardOffset {
    NSNumber *number = objc_getAssociatedObject(self, MOKeyboardOffsetKey);
    CGFloat offset = number.floatValue <= 0.0 ? 10.0 : number.floatValue;
    return offset;
}

- (void)setShouldObserveKeyboard:(BOOL)shouldObserveKeyboard {
    if (shouldObserveKeyboard) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    } else {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    objc_setAssociatedObject(self, MOKeyboardShouldObserveKey, @(shouldObserveKeyboard), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)shouldObserveKeyboard {
    return [objc_getAssociatedObject(self, MOKeyboardShouldObserveKey) intValue];
}


- (void)initNavigationItemWithTitle:(NSString *)title backgroundColor:(UIColor *)color showLine:(BOOL)show {
    
    //标题
    if (title) self.navigationItem.title = title;
    
    //设置背景
    if (!self.navigationView) {
        self.navigationView = [[MONavigationView alloc] initWithBackgroundColor:color];
        if (self.presentingViewController && self.modalPresentationStyle == UIModalPresentationPageSheet) {
            self.navigationView.height = 54;
        }
    } else {
        self.navigationView.backgroundColor = color;
    }
    if (show) [self.navigationView lineView];
    [self.view addSubview:self.navigationView];
}

- (void)setNavigationStyle:(MONavigationStyle)navigationStyle {
    
    if (self.navigationStyle == navigationStyle) return;
    objc_setAssociatedObject(self, MONavigationStyleKey, @(navigationStyle), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    switch (self.navigationStyle) {
        case MONavigationStyleDarkContent:
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
            self.navigationController.navigationBar.tintColor = [UIColor blackColor];
            [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]}];
            break;
            
        case MONavigationStyleLightContent:
            [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
            self.navigationController.navigationBar.tintColor = UIColor.whiteColor;
            [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName :[UIColor whiteColor]}];
            break;
            
        default:
            break;
    }
}

- (MONavigationStyle)navigationStyle {
    NSNumber *style = objc_getAssociatedObject(self, MONavigationStyleKey);
    if (!style) {
        style = @(0);
        objc_setAssociatedObject(self, MONavigationStyleKey, style, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return style.intValue;
}

#pragma mark - 键盘监听
- (void)keyboardWillShow:(NSNotification *)noti {
    
    UIView *responseView = [self firstResponderWithView:self.view];
    CGRect responseFrame = [self.view convertRect:responseView.frame fromView:responseView.superview];
    CGRect keyboardFrame = [noti.userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
    double animationTimes = [noti.userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] doubleValue];
    CGFloat offY = keyboardFrame.origin.y - (responseFrame.origin.y + responseFrame.size.height + self.keyboardOffset);
    if (offY > 0) offY = 0;
    
    UIView *frontView = self.view.subviews.lastObject;
    if (frontView != self.navigationView) {
        [self.view addSubview:self.navigationView];
    }
    [UIView animateWithDuration:animationTimes animations:^{
        CGRect frame = self.view.frame;
        frame.origin.y = offY;
        self.navigationView.y = -offY;
        self.view.frame = frame;
    }];
}


- (void)keyboardWillHide:(NSNotification *)noti {
    
    double animationTimes = [noti.userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] doubleValue];
    [UIView animateWithDuration:animationTimes animations:^{
        CGRect frame = self.view.frame;
        frame.origin.y = 0;
        self.view.frame = frame;
        self.navigationView.y = 0;
    }];
}


- (UIView *)firstResponderWithView:(UIView *)view {
    
    if([view isFirstResponder]) {
        return view;
    }
    
    for (UIView *subView in view.subviews) {
        UIView *firstResponder = [self firstResponderWithView:subView];
        if(firstResponder) {
            return firstResponder;
        }
    }
    return nil;
}



- (void)af_dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
    if (@available(iOS 11.0, *)){
        if ([self isKindOfClass:UIImagePickerController.class] || [self isKindOfClass:UIDocumentPickerViewController.class]) {
            UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"presentVCDismiss" object:nil];
    [self af_dismissViewControllerAnimated:flag completion:completion];
}

- (void)af_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    if ([self isEqual:viewControllerToPresent]) {
        return;
    }
    
    
    if ([viewControllerToPresent isKindOfClass:UIImagePickerController.class] || [viewControllerToPresent isKindOfClass:UIDocumentPickerViewController.class]) {
        if (@available(iOS 11.0, *)){
            UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
        } else {
            viewControllerToPresent.automaticallyAdjustsScrollViewInsets = YES;
        }
    }
    [self af_presentViewController:viewControllerToPresent animated:flag completion:^{
        if (viewControllerToPresent.modalPresentationStyle != UIModalPresentationFullScreen || (viewControllerToPresent.presentingViewController && viewControllerToPresent.presentingViewController.modalPresentationStyle != UIModalPresentationFullScreen)) {
            [NSNotificationCenter.defaultCenter postNotificationName:@"MONotification_PresentModalNotFullScreen" object:viewControllerToPresent];
        }
        if (completion) {
            completion();
        }
    }];
}

@end


@implementation UITableViewController (MONavigation)

+(void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleInstanceMethodWithClass:[self class] originalSel:@selector(scrollViewDidScroll:) swizzledSel:@selector(af_scrollViewDidScroll:)];
    });
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
}


- (void)af_scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.navigationView && scrollView == self.view) {
        self.navigationView.y = scrollView.contentOffset.y;
        if (self.view.subviews.lastObject != self.navigationView) {
            [self.view addSubview:self.navigationView];
        }
    }
    [self af_scrollViewDidScroll:scrollView];
}

@end


@implementation UINavigationBar (MONavigation)

+(void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleInstanceMethodWithClass:[UINavigationBar class] originalSel:@selector(setTranslucent:) swizzledSel:@selector(af_setTranslucent:)];
    });
}


- (void)af_setTranslucent:(BOOL)translucent {
    [self af_setTranslucent:YES];
}


@end


